package music;

import graphics.GuitarKeys;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.sampled.FloatControl;

public class Song {
	Sequencer sequencer;
	Sequence sequence;
	OggFile guitarAudio;
	OggFile rhythmAudio;
	OggFile songAudio;

	List<Note> notes;
	int nextNote = 0;

	long startTime;
	long maxDiff = 100;

	public Song(String dir) {
		notes = new ArrayList<Note>();
		loadDir(dir);
	}

	private Note getNote(long time) {
		for (Note note : notes) {
			if (time < note.getTime() + 10)
				return note;
		}
		return null;
	}

	public int loadDir(String string) {
		// int level = 0x60; //Amazing
		// int level = 0x54; //Medium
		int level = 0x48; // Easy
		// int level = 0x3c; //SupaEasy

		// for (int i = 0; i < 30; i++) {
		// Note note = new Note(i * 1000);
		// note.set(i % 5);
		// notesLeft.add(note);
		// }
		//
		File path = new File(string);
		if (!path.isDirectory()) {
			System.out.println("Path must be a directory");
			return -1;
		}

		File midiFile = new File(string + "/notes.mid");
		if (!midiFile.exists()) {
			System.out.println("Could't find notes.mid in "
					+ path.getAbsoluteFile());
			return -1;
		}
		File guitarFile = new File(string + "/guitar.ogg");
		if (!guitarFile.exists()) {
			System.out.println("Could't find guitar.ogg in "
					+ path.getAbsoluteFile());
			return -1;
		}
		File songFile = new File(string + "/song.ogg");
		if (!songFile.exists()) {
			System.out.println("Could't find song.ogg in "
					+ path.getAbsoluteFile());
			return -1;
		}
		try {
			System.out.println(midiFile.getAbsoluteFile());
			sequence = MidiSystem.getSequence(midiFile);
			System.out.println(sequence.getTracks().length);
			for (int i = 0; i < sequence.getTracks()[1].size(); i++) {
				MidiEvent event = sequence.getTracks()[1].get(i);
				int key = event.getMessage().getMessage()[1];
				if (key >= level && key < level + 5) {
					// System.out.println(event.getTick() + " "
					// + event.getMessage().getLength() + " "
					// + event.getMessage().getStatus() + " "
					// + event.getMessage().getMessage()[0] + " "
					// // + event.getMessage().getMessage()[1] + " "
					// + event.getMessage().getMessage()[2]);
					long time = event.getTick();
					Note note = getNote(time);
					if (note == null) {
						note = new Note(time);
						notes.add(note);
					}
					note.set(key - level);
				}
			}
		} catch (InvalidMidiDataException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		guitarAudio = new OggFile(guitarFile);
		guitarAudio.start();
		songAudio = new OggFile(songFile);
		songAudio.start();
		return 0;
	}

	public Note getNextNote() {
		return notes.get(nextNote);
	}

	public long getTime() {
		long time = 0;
		if (songAudio != null)
			time = songAudio.getTime();
		return time;
	}

	public void muteGuitar(int playerNumber) {
		FloatControl control = guitarAudio.getControl();
		if (control != null)
			control.setValue(-20.0f);
	}

	public void unMuteGuitar(int playerNumber) {
		guitarAudio.getControl().setValue(0.0f);
	}

	public void start() {
		startTime = System.currentTimeMillis();
		guitarAudio.play(songAudio);
		songAudio.play();
	}

	public void update() {
		long thisTime = getTime();
		Note note = getNextNote();
		if (thisTime > note.getTime() + maxDiff) {
			nextNote++;
			// missedNote(note);
		}
	}

	public boolean hit(int playerNumber, GuitarKeys guitarKeys) {
		long thisTime = getTime();
		Note note = getNextNote();
		if (note.getTime() - maxDiff < thisTime)
			if (note.check(guitarKeys))
				return true;
		return false;
	}

	public List<Note> getNotes() {
		return notes;
	}

	public int getNextNoteNumber() {
		return nextNote;
	}
}
